package com.shlh.saas.controller;

import com.shlh.saas.common.Result;
import com.shlh.saas.common.UserContext;
import com.shlh.saas.entity.UserBalance;
import com.shlh.saas.service.DomainLookupService;
import com.shlh.saas.service.UserBalanceService;
import com.shlh.saas.service.WorkbenchStatsService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 域名反查控制器
 * 提供通过域名查询相关企业或用户信息的API
 */
@RestController
@RequestMapping("/domain-lookup")
public class DomainLookupController {

    private static final Logger log = LoggerFactory.getLogger(DomainLookupController.class);
    
    // 创建线程池用于并发搜索
    private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    @Autowired
    private DomainLookupService domainLookupService;
    
    @Autowired
    private WorkbenchStatsService workbenchStatsService;
    
    @Autowired
    private UserBalanceService userBalanceService;

    /**
     * 域名反查API
     * 通过域名查询相关企业或用户信息
     * 
     * @param domain 域名
     * @param page 页码
     * @param size 每页数量
     * @return 查询结果
     */
    @GetMapping("")
    public Map<String, Object> lookupByDomain(
            @RequestParam String domain,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        
        // 添加详细调试日志
        log.info("收到域名反查请求: 域名={}, 页码={}, 页大小={}", domain, page, size);

        Long userId = UserContext.getUserId();
        // 域名基本验证
        if (domain == null || domain.trim().isEmpty()) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("results", Collections.emptyList());
            errorResponse.put("total", 0);
            errorResponse.put("page", page);
            errorResponse.put("size", size);
            errorResponse.put("error", "域名不能为空");
            return errorResponse;
        }
        
        // 域名反查属于特殊操作，无论是第几页都需要扣除额度
            // 检查用户余额
            UserBalance userBalance = userBalanceService.getByUserId(userId);
            if (userBalance == null || userBalance.getReverseLookupRemaining() < size) {
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("results", Collections.emptyList());
                errorResult.put("total", 0);
                errorResult.put("page", page);
                errorResult.put("size", size);
                errorResult.put("error", "您的反查次数余额不足，请充值后再查看");
                return errorResult;
            }
            
            // 调用服务进行查询
            Map<String, Object> result = domainLookupService.lookupByDomain(domain, page, size);
            log.info("查询结果总数: {}", result.containsKey("total") ? result.get("total") : "未知");
            log.info("查询结果: {}", result.containsKey("results") ? result.get("results") : "未知");

            // 获取实际返回的数据条数
            int actualCount = 0;
            if (result.containsKey("results") && result.get("results") instanceof List) {
                actualCount = ((List<?>) result.get("results")).size();
            }
            
            // 扣除用户反查余额
            if (actualCount > 0) {
                userBalanceService.deductReverseLookup(userId, actualCount);
            }
            
            // 增加域名反查次数统计
            workbenchStatsService.incrementDomainLookupCount(userId);
            
            return result;
    }

    /**
     * 批量域名反查接口
     * 读取Excel文件并进行批量域名反查，返回Excel结果文件
     */
    @PostMapping("/batch")
    public ResponseEntity<?> batchDomainLookup(@RequestParam("file") MultipartFile file) {
        log.info("收到批量域名反查请求");

        // 获取当前用户ID
        Long userId = UserContext.getUserId();

        try {
            // 检查文件
            if (file.isEmpty()) {
                return ResponseEntity.badRequest().body(Result.error("请选择要上传的Excel文件"));
            }

            String fileName = file.getOriginalFilename();
            if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
                return ResponseEntity.badRequest().body(Result.error("文件格式不正确，只支持.xlsx和.xls格式"));
            }

            // 读取Excel文件
            Workbook workbook = WorkbookFactory.create(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);
            int totalRows = sheet.getPhysicalNumberOfRows();

            if (totalRows <= 1) {
                workbook.close();
                return ResponseEntity.badRequest().body(Result.error("上传的Excel文件没有数据"));
            }

            // 读取表头
            Row headerRow = sheet.getRow(0);
            Map<String, Integer> headerMap = new HashMap<>();
            for (int i = 0; i < headerRow.getPhysicalNumberOfCells(); i++) {
                Cell cell = headerRow.getCell(i);
                if (cell != null) {
                    headerMap.put(cell.getStringCellValue().toLowerCase(), i);
                }
            }

            // 查找域名列
            Integer domainColumnIndex = null;
            for (String key : headerMap.keySet()) {
                if (key.contains("domain") || key.contains("域名") || key.contains("website") || key.contains("网址") || key.contains("网站")) {
                    domainColumnIndex = headerMap.get(key);
                    log.info("识别到域名列: {}", key);
                    break;
                }
            }

            if (domainColumnIndex == null) {
                workbook.close();
                return ResponseEntity.badRequest().body(Result.error("无法识别Excel表头，请确保表头包含'Domain'、'域名'、'Website'或'网址'列"));
            }

            // 检查用户余额
            UserBalance userBalance = userBalanceService.getByUserId(userId);
            if (userBalance == null || userBalance.getReverseLookupRemaining() <= 0) {
                workbook.close();
                return ResponseEntity.badRequest().body(Result.error("您的反查次数余额不足，请充值后再使用"));
            }

            // 准备结果文件
            Workbook resultWorkbook = new XSSFWorkbook();

            // 创建4个sheet对应不同数据源
            Sheet linkedinSheet = createSheetWithHeader(resultWorkbook, "LinkedIn数据", getLinkedInHeaders());
            Sheet companySheet = createSheetWithHeader(resultWorkbook, "全球企业库", getCompanyHeaders());
            Sheet buyerSheet = createSheetWithHeader(resultWorkbook, "广交会采购商", getBuyerHeaders());
            Sheet exhibitorSheet = createSheetWithHeader(resultWorkbook, "广交会展商", getExhibitorHeaders());

            // 统计各数据源找到的结果数量
            Map<String, Integer> resultCounts = new HashMap<>();
            resultCounts.put("linkedin", 0);
            resultCounts.put("company", 0);
            resultCounts.put("buyer", 0);
            resultCounts.put("exhibitor", 0);

            // 遍历数据行
            for (int rowNum = 1; rowNum < totalRows; rowNum++) {
                Row dataRow = sheet.getRow(rowNum);
                if (dataRow == null) continue;

                // 获取域名
                String domain = getCellStringValue(dataRow, domainColumnIndex);
                
                if (domain == null || domain.trim().isEmpty()) {
                    continue;
                }

                // 并行搜索4个数据源
                List<CompletableFuture<Void>> searchTasks = new ArrayList<>();

                // 搜索LinkedIn数据
                searchTasks.add(CompletableFuture.runAsync(() -> {
                    try {
                        List<Map<String, Object>> results = domainLookupService.searchLinkedInByDomain(domain);
                        if (!results.isEmpty()) {
                            synchronized (linkedinSheet) {
                                for (Map<String, Object> result : results) {
                                    addDataToSheet(linkedinSheet, result, getLinkedInHeaders());
                                    resultCounts.put("linkedin", resultCounts.get("linkedin") + 1);
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("搜索LinkedIn数据异常: domain={}", domain, e);
                    }
                }, executorService));

                // 搜索全球企业库数据
                searchTasks.add(CompletableFuture.runAsync(() -> {
                    try {
                        List<Map<String, Object>> results = domainLookupService.searchCompanyByDomain(domain);
                        if (!results.isEmpty()) {
                            synchronized (companySheet) {
                                for (Map<String, Object> result : results) {
                                    addDataToSheet(companySheet, result, getCompanyHeaders());
                                    resultCounts.put("company", resultCounts.get("company") + 1);
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("搜索全球企业库数据异常: domain={}", domain, e);
                    }
                }, executorService));

                // 搜索广交会采购商数据
                searchTasks.add(CompletableFuture.runAsync(() -> {
                    try {
                        List<Map<String, Object>> results = domainLookupService.searchBuyerByDomain(domain);
                        if (!results.isEmpty()) {
                            synchronized (buyerSheet) {
                                for (Map<String, Object> result : results) {
                                    addDataToSheet(buyerSheet, result, getBuyerHeaders());
                                    resultCounts.put("buyer", resultCounts.get("buyer") + 1);
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("搜索广交会采购商数据异常: domain={}", domain, e);
                    }
                }, executorService));

                // 搜索广交会展商数据
                searchTasks.add(CompletableFuture.runAsync(() -> {
                    try {
                        List<Map<String, Object>> results = domainLookupService.searchExhibitorByDomain(domain);
                        if (!results.isEmpty()) {
                            synchronized (exhibitorSheet) {
                                for (Map<String, Object> result : results) {
                                    addDataToSheet(exhibitorSheet, result, getExhibitorHeaders());
                                    resultCounts.put("exhibitor", resultCounts.get("exhibitor") + 1);
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("搜索广交会展商数据异常: domain={}", domain, e);
                    }
                }, executorService));

                // 等待所有搜索任务完成
                CompletableFuture.allOf(searchTasks.toArray(new CompletableFuture[0])).join();
            }

            workbook.close();

            // 计算总扣除额度
            int totalDeduction = resultCounts.values().stream().mapToInt(Integer::intValue).sum();

            // 检查余额是否足够
            if (userBalance.getReverseLookupRemaining() < totalDeduction) {
                resultWorkbook.close();
                return ResponseEntity.badRequest().body(Result.error("您的反查次数余额不足，需要扣除 " + totalDeduction + " 次，当前余额 " + userBalance.getReverseLookupRemaining() + " 次"));
            }

            // 移除没有数据的sheet
            removeEmptySheets(resultWorkbook);

            // 扣除用户反查余额
            if (totalDeduction > 0) {
                userBalanceService.deductReverseLookup(userId, totalDeduction);
            }

            // 增加域名反查次数统计
            workbenchStatsService.incrementDomainLookupCount(userId);

            // 将结果Excel写入字节数组
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            resultWorkbook.write(outputStream);
            resultWorkbook.close();

            byte[] excelBytes = outputStream.toByteArray();
            outputStream.close();

            // 设置响应头
            String resultFileName = "批量域名反查结果_" + System.currentTimeMillis() + ".xlsx";
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", java.net.URLEncoder.encode(resultFileName, "UTF-8"));
            headers.setContentLength(excelBytes.length);

            log.info("批量域名反查完成: 处理{}行数据，扣除{}次额度", totalRows - 1, totalDeduction);

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(excelBytes);

        } catch (Exception e) {
            log.error("批量域名反查异常", e);
            return ResponseEntity.status(500).body(Result.error("批量域名反查异常: " + e.getMessage()));
        }
    }

    // 创建带表头的sheet
    private Sheet createSheetWithHeader(Workbook workbook, String sheetName, String[] headers) {
        Sheet sheet = workbook.createSheet(sheetName);
        Row headerRow = sheet.createRow(0);
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }
        return sheet;
    }

    // 移除没有数据的sheet
    private void removeEmptySheets(Workbook workbook) {
        for (int i = workbook.getNumberOfSheets() - 1; i >= 0; i--) {
            Sheet sheet = workbook.getSheetAt(i);
            if (sheet.getLastRowNum() <= 0) {
                log.info("移除空sheet: {}", sheet.getSheetName());
                workbook.removeSheetAt(i);
            }
        }
    }

    // 添加数据到sheet
    private void addDataToSheet(Sheet sheet, Map<String, Object> data, String[] headers) {
        int lastRowNum = sheet.getLastRowNum();
        Row row = sheet.createRow(lastRowNum + 1);

        for (int i = 0; i < headers.length; i++) {
            String header = headers[i];
            Object value = data.get(header);
            Cell cell = row.createCell(i);

            if (value != null) {
                if (value instanceof String) {
                    cell.setCellValue((String) value);
                } else if (value instanceof Number) {
                    cell.setCellValue(((Number) value).doubleValue());
                } else if (value instanceof Date) {
                    cell.setCellValue((Date) value);
                } else {
                    cell.setCellValue(value.toString());
                }
            } else {
                cell.setCellValue("");
            }
        }
    }

    // 获取单元格字符串值
    private String getCellStringValue(Row row, Integer columnIndex) {
        if (columnIndex == null || row == null) {
            return null;
        }
        Cell cell = row.getCell(columnIndex);
        if (cell == null) {
            return null;
        }
        return switch (cell.getCellType()) {
            case STRING -> cell.getStringCellValue().trim();
            case NUMERIC -> String.valueOf((long) cell.getNumericCellValue());
            case BOOLEAN -> String.valueOf(cell.getBooleanCellValue());
            default -> null;
        };
    }

    // 各数据源的表头定义
    private String[] getLinkedInHeaders() {
        return new String[]{"公司名", "人名", "网址", "职位", "行业", "邮箱", "电话", "手机号", "位置", "地点", "国家", "公司规模", "twitter用户", "twitter链接", "LinkedIn链接", "GitHub链接", "Facebook链接"};
    }

    private String[] getCompanyHeaders() {
        return new String[]{"公司名", "姓名", "职位", "省份", "行业", "子行业", "员工规模", "收入规模", "电话", "手机号", "网址", "邮箱", "地址", "邮编"};
    }

    private String[] getBuyerHeaders() {
        return new String[]{"公司名", "联系人", "国家/地区", "采购类型", "网址", "邮箱", "电话", "传真", "地址", "邮编", "广交会届数"};
    }

    private String[] getExhibitorHeaders() {
        return new String[]{"公司名", "公司类型", "公司简介", "联系人", "手机号", "固定电话", "网址", "地址", "邮箱", "传真", "邮编", "行业", "省份", "展位号", "主要产品", "公司规模", "成立年份", "注册资金", "历史参展", "届次"};
    }

    /**
     * 下载批量域名反查模板
     * @param lang 语言（zh/en）
     */
    @GetMapping("/batch/template")
    public ResponseEntity<byte[]> downloadTemplate(@RequestParam(defaultValue = "zh") String lang) {
        try {
            String templatePath;
            String fileName;
            
            if ("en".equals(lang)) {
                templatePath = "static/templates/domain/Domain Reverse.xls";
                fileName = "Domain_Reverse.xls";
            } else {
                templatePath = "static/templates/domain/域名反查.xls";
                fileName = "域名反查.xls";
            }
            
            Resource resource = new ClassPathResource(templatePath);
            InputStream inputStream = resource.getInputStream();
            byte[] bytes = inputStream.readAllBytes();
            inputStream.close();
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", java.net.URLEncoder.encode(fileName, "UTF-8"));
            headers.setContentLength(bytes.length);
            
            return ResponseEntity.ok().headers(headers).body(bytes);
        } catch (Exception e) {
            log.error("下载模板失败", e);
            return ResponseEntity.status(500).body(null);
        }
    }
} 